package cn.xie.blog.serverutil.util;

import java.lang.reflect.Type;
import java.util.List;
import cn.hutool.core.lang.TypeReference;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.Feature;
import lombok.experimental.UtilityClass;

/**
 * @author: xiaoxie
 * create: 2025-04-22 17:14
 * @BelongsProject: blog-parent
 * @BelongsPackage: cn.xie.blog.serverutil.util
 * description: json工具类
 */
@UtilityClass
public class JSONUtil extends cn.hutool.json.JSONUtil {

    /**
     * JSON字符串转为实体类对象，转换异常将被抛出
     *
     * @param <T>        Bean类型
     * @param jsonString JSON字符串
     * @param beanClass  实体类对象
     * @return 实体类对象
     * @since 3.1.2
     */
    public static <T> T toBean(String jsonString, Class<T> beanClass) {
        return JSON.toJavaObject(JSON.parseObject(jsonString, Feature.AllowISO8601DateFormat), beanClass);
    }

    /**
     * 转为实体类对象，转换异常将被抛出
     *
     * @param <T>       Bean类型
     * @param json      JSONObject
     * @param beanClass 实体类对象
     * @return 实体类对象
     */
    public static <T> T toBean(JSONObject json, Class<T> beanClass) {
        return null == json ? null : JSON.toJavaObject(JSON.parseObject(json.toString(), Feature.AllowISO8601DateFormat), beanClass);
    }


    /**
     * JSON字符串转为实体类对象，转换异常将被抛出
     *
     * @param <T>           Bean类型
     * @param jsonString    JSON字符串
     * @param typeReference {@link TypeReference}类型参考子类，可以获取其泛型参数中的Type类型
     * @param ignoreError   是否忽略错误
     * @return 实体类对象
     * @since 4.3.2
     */
    public static <T> T toBean(String jsonString, TypeReference<T> typeReference, boolean ignoreError) {
        try {
            return JSON.parseObject(jsonString, typeReference.getType(), Feature.AllowISO8601DateFormat);
        } catch (Exception e) {
            if (ignoreError) {
                return null;
            } else {
                throw new RuntimeException("JSON 解析 异常", e);
            }
        }
    }

    /**
     * JSON字符串转为实体类对象，转换异常将被抛出
     *
     * @param <T>         Bean类型
     * @param jsonString  JSON字符串
     * @param beanType    实体类对象类型
     * @param ignoreError 是否忽略错误
     * @return 实体类对象
     * @since 4.3.2
     */
    public static <T> T toBean(String jsonString, Type beanType, boolean ignoreError) {
        return JSON.parseObject(jsonString, beanType);
    }

    /**
     * 转为实体类对象
     *
     * @param <T>           Bean类型
     * @param json          JSONObject
     * @param typeReference {@link TypeReference}类型参考子类，可以获取其泛型参数中的Type类型
     * @param ignoreError   是否忽略转换错误
     * @return 实体类对象
     * @since 4.6.2
     */
    public static <T> T toBean(cn.hutool.json.JSON json, TypeReference<T> typeReference, boolean ignoreError) {
        return JSON.parseObject(toJsonStr(json), typeReference.getType());
    }

    /**
     * 转为实体类对象
     *
     * @param <T>         Bean类型
     * @param json        JSONObject
     * @param beanType    实体类对象类型
     * @param ignoreError 是否忽略转换错误
     * @return 实体类对象
     * @since 4.3.2
     */
    public static <T> T toBean(cn.hutool.json.JSON json, Type beanType, boolean ignoreError) {
        if (null == json) {
            return null;
        }
        return JSON.parseObject(toJsonStr(json), beanType);
    }


    /**
     * 将JSONArray字符串转换为Bean的List，默认为ArrayList
     *
     * @param <T>         Bean类型
     * @param jsonArray   JSONArray字符串
     * @param elementType List中元素类型
     * @return List
     * @since 5.5.2
     */
    public static <T> List<T> toList(String jsonArray, Class<T> elementType) {
        return JSON.parseArray(jsonArray, elementType);
    }

    /**
     * 将JSONArray转换为Bean的List，默认为ArrayList
     *
     * @param <T>         Bean类型
     * @param jsonArray   {@link JSONArray}
     * @param elementType List中元素类型
     * @return List
     * @since 4.0.7
     */
    public static <T> List<T> toList(JSONArray jsonArray, Class<T> elementType) {
        return JSON.parseArray(toJsonStr(jsonArray), elementType);
    }
}
